#!/usr/bin/env bash
set -e

# ============ Config ============
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
SERVER_DIR="$PROJECT_DIR"
COMPOSE_FILE="$SERVER_DIR/docker-compose.yml"
ENV_DOCKER_FILE="$SERVER_DIR/.env.docker"
APP_ENV_FILE="$SERVER_DIR/.env"
USE_MIGRATE=0
RUN_SEED=1
RESET_DB=0
SKIP_NPM_INSTALL=0

# ============ Colors ============
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# ============ Helpers ============
log() { echo -e "${BLUE}[$(date +%H:%M:%S)]${NC} $1"; }
ok() { echo -e "${GREEN}✓${NC} $1"; }
warn() { echo -e "${YELLOW}!${NC} $1"; }
err() { echo -e "${RED}✗${NC} $1"; }
need() { command -v "$1" >/dev/null 2>&1 || { err "缺少命令: $1"; exit 1; }; }

usage() {
  cat <<EOF
用法: ./install.sh [选项]

选项:
  --migrate        使用 prisma migrate（记录迁移历史），默认使用 db push
  --no-seed        不执行种子数据
  --reset-db       重置数据库容器与数据卷（docker compose down -v 后再 up）
  --skip-npm       跳过 npm install（已安装过依赖时可用）
  -h, --help       查看帮助

示例:
  ./install.sh                    # 一键启动DB, 同步表结构, 生成客户端, 执行种子
  ./install.sh --migrate          # 使用迁移而不是 db push
  ./install.sh --reset-db --skip-npm
EOF
}

for arg in "$@"; do
  case "$arg" in
    --migrate) USE_MIGRATE=1 ;;
    --no-seed) RUN_SEED=0 ;;
    --reset-db) RESET_DB=1 ;;
    --skip-npm) SKIP_NPM_INSTALL=1 ;;
    -h|--help) usage; exit 0 ;;
    *) warn "未知参数: $arg" ;;
  esac
done

# ============ Checks ============
need docker
need node
need npm
if docker compose version >/dev/null 2>&1; then :; else err "需要 Docker Compose v2: 请安装 Docker Desktop 或 docker-compose-plugin"; exit 1; fi

if [ ! -f "$COMPOSE_FILE" ]; then err "未找到 $COMPOSE_FILE"; exit 1; fi
if [ ! -f "$ENV_DOCKER_FILE" ]; then err "未找到 $ENV_DOCKER_FILE"; exit 1; fi

cd "$SERVER_DIR"

# ============ Bring up DB ============
if [ $RESET_DB -eq 1 ]; then
  log "重置数据库容器与数据卷..."
  docker compose --env-file "$ENV_DOCKER_FILE" down -v || true
fi

log "启动 Docker 数据库与 Adminer..."
docker compose --env-file "$ENV_DOCKER_FILE" up -d

# Wait for MySQL healthy
log "等待 MySQL 就绪(health=healthy)..."
ATTEMPTS=60
SLEEP=2
for i in $(seq 1 $ATTEMPTS); do
  STATUS=$(docker inspect -f '{{.State.Health.Status}}' message-mysql 2>/dev/null || echo "")
  if [ "$STATUS" = "healthy" ]; then ok "MySQL 已就绪"; break; fi
  sleep $SLEEP
  if [ $i -eq $ATTEMPTS ]; then err "等待 MySQL 健康超时"; exit 1; fi
done

# ============ Ensure .env ============
if [ ! -f "$APP_ENV_FILE" ]; then
  # Parse MYSQL_PORT from .env.docker (default 3306)
  MYSQL_PORT=$(grep -E '^MYSQL_PORT=' "$ENV_DOCKER_FILE" | cut -d'=' -f2 | tr -d '\r')
  [ -z "$MYSQL_PORT" ] && MYSQL_PORT=3306
  cat > "$APP_ENV_FILE" <<ENV
# Auto generated by install.sh
DATABASE_URL="mysql://msg:MsgPass!123@127.0.0.1:${MYSQL_PORT}/message?connection_limit=5&pool_timeout=10"
ENV
  ok "已生成 $APP_ENV_FILE"
else
  warn "$APP_ENV_FILE 已存在，跳过生成"
fi

# ============ NPM install ============
if [ $SKIP_NPM_INSTALL -eq 0 ]; then
  log "安装后端依赖..."
  npm install --force
else
  warn "跳过 npm install"
fi

# ============ Prisma ============
log "同步数据库结构..."
if [ $USE_MIGRATE -eq 1 ]; then
  npx prisma migrate dev -n init
else
  npx prisma db push
fi

ok "生成 Prisma Client"
npx prisma generate

if [ $RUN_SEED -eq 1 ]; then
  if [ -f "$SERVER_DIR/prisma/seed.mjs" ]; then
    log "执行种子数据..."
    npx prisma db seed
  else
    warn "未找到 prisma/seed.mjs，跳过种子"
  fi
else
  warn "按参数 --no-seed 跳过种子"
fi

# ============ Summary ============
ok "初始化完成！"
echo ""
echo "访问 Adminer 管理： http://127.0.0.1:$(grep -E '^ADMINER_PORT=' "$ENV_DOCKER_FILE" | cut -d'=' -f2 | tr -d '\r' | sed 's/^$/8080/')" \
     "(服务器填 mysql，用户 msg，库 message)"
echo "Swagger 文档：     http://127.0.0.1:7001/swagger-ui/index.html"
echo "运行后端开发：     pnpm dev  (或 yarn dev / npm run dev)"
echo ""
ok "可使用参数： --migrate | --no-seed | --reset-db | --skip-npm"
